﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
using System.Net;

namespace FusionDotNet
{
    /// <summary>
    /// Base implementation of commands that require an HTTP GET such as SELECT.
    /// </summary>
    /// <typeparam name="TResult">Type of <seealso cref="CommandResult"/> that this command returns.</typeparam>
    public abstract class GetCommand<TResult> : Command<TResult> where TResult : CommandResult, new()
    {
        private const string COMMAND_PREFIX = "?sql=";

        /// <summary>
        /// Allows derived classes to specify the command appended to the base Uri after the Command Prefix.
        /// </summary>
        /// <returns>String to use as the Query string.</returns>
        protected virtual string GetCommandQueryString()
        {
            return string.Empty;
        }

        /// <summary>
        /// Allows derived classes to specify a prefix that is appended to the base Uri. The default fusion Prefix is "?sql=";
        /// </summary>
        /// <returns></returns>
        protected virtual string GetCommandPrefix()
        {
            return COMMAND_PREFIX;
        }

        /// <summary>
        /// Builds the Uri for the request in the form of base Uri - Command Prefix - Command Query String.
        /// </summary>
        /// <returns></returns>
        protected override string GetRequestUri()
        {
            string baseUriString = base.GetRequestUri();
            string commandPrefix = GetCommandPrefix();
            string query = HttpUtility.UrlEncode(GetCommandQueryString());
            string commandUri = string.Format("{0}{1}{2}", baseUriString, commandPrefix, query);
            return commandUri;
        }
        
        /// <summary>
        /// Synchronously execute the GET command.
        /// </summary>
        /// <returns><see cref="Stream"/> containing the results of the GET command.</returns>
        protected override Stream ExecuteCommand()
        {
            HttpWebRequest request = CreateWebRequest();
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            CheckForLoginRedirect(request, response);

            return response.GetResponseStream();
        }

        /// <summary>
        /// Asynchronously execute the GET command.
        /// </summary>
        protected override void ExecuteCommandAsync()
        {
            HttpWebRequest request = CreateWebRequest();

            RequestState state = new RequestState(request);

            IAsyncResult result = request.BeginGetResponse(this.ExecuteComplete, state);

            if (result.CompletedSynchronously)
            {
                IsBusy = false;
            }
            else
            {
                IsBusy = true;
            }
        }




     
    }
}
